home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / macros / latex209 / contrib / misc / trigonometry.tex < prev    next >
Text File  |  1991-10-05  |  6KB  |  207 lines

  1. %= = = = = = = = = = = = = T R I G O N O M E T R Y . T E X = = = = = = = = =
  2.  
  3. %%% Trigonometry.TeX: (as published in TeXhax Digest, September 1989)
  4. %%% Philip Taylor, Royal Holloway and Bedford New College, University of London
  5.  
  6. %%% Routines to calculate the sine of an angle expressed in radians.
  7. %%% So far as I can tell, the results are accurate to four places
  8. %%% of decimals, for arguments in the range -pi/2 .. pi/2, except
  9. %%% for `ridiculously small' arguments, which cannot be accurately represented.
  10.  
  11. %%% The routines for cosine and tangent are left to the reader ...
  12.  
  13. %%% After a call to \Sin (<angle>), the result is available for typesetting
  14. %%% or boxing, and may also be extracted from the control-sequence \sine.
  15.  
  16. %%% Grouping is used to hide most things, but the following csnames are
  17. %%% globally defined:
  18.  
  19. %%% \nodimen, \n@dimen, \product, \sine, \term, \t@rm, \Term
  20.  
  21. \newif \ifdebug %%% turn me on to see TeX hard at work ...
  22.  
  23. \def \term #1{{x^{#1} \over #1!}}
  24. The power series expansion for $\sin$ is:
  25. $$ \sin x = x - \term3 + \term5 - \term7 + \cdots$$
  26. \indent and for $\cos$ is:
  27. $$ \cos x = 1 - \term2 + \term4 - \term6 + \cdots$$
  28.  
  29. \let \then = \relax
  30. \chardef \letter = 11
  31. \chardef \other = 12
  32. \def \radian {pt }
  33. \let \radians = \radian
  34. \let \dimensionlessunit = \radian
  35. \let \dimensionlessunits = \dimensionlessunit
  36. \def \internalunit {sp }
  37. \let \internalunits = \internalunit
  38. \newif \ifstillconverging
  39. \def \Message #1{\ifdebug \then \message {#1} \fi}
  40.  
  41. { %%% Things that need abnormal catcodes %%%
  42.     \catcode `\@ = \letter
  43.     \gdef \nodimen {\expandafter \n@dimen \the \dimen}
  44.     \gdef \term #1 #2 #3%
  45.            {\edef \t@ {\the #1}%%% freeze parameter 1 (count, by value)
  46.         \edef \t@@ {\expandafter \n@dimen \the #2\radian}%
  47.                    %%% freeze parameter 2 (dimen, by value)
  48.         \t@rm {\t@} {\t@@} {#3}%
  49.            }
  50.     \gdef \t@rm #1 #2 #3%
  51.            {{%
  52.         \count 0 = 0
  53.         \dimen 0 = 1 \dimensionlessunit
  54.         \dimen 2 = #2\relax
  55.         \Message {Calculating term #1 of \nodimen 2}%
  56.         \loop
  57.         \ifnum    \count 0 < #1
  58.         \then    \advance \count 0 by 1
  59.             \Message {Iteration \the \count 0 \space}%
  60.             \Multiply \dimen 0 by {\dimen 2}%
  61.             \Message {After multiplication, term = \nodimen 0}%
  62.             \Divide \dimen 0 by {\count 0}%
  63.             \Message {After division, term = \nodimen 0}%
  64.         \repeat
  65.         \Message {Final value for term #1 of
  66.                 \nodimen 2 \space is \nodimen 0}%
  67.         \xdef \Term {#3 = \nodimen 0 \radians}%
  68.         \aftergroup \Term
  69.            }}
  70.     \catcode `\p = \other
  71.     \catcode `\t = \other
  72.     \gdef \n@dimen #1pt{#1} %%% throw away the ``pt''
  73. }
  74.  
  75. \def \Divide #1by #2{\divide #1 by #2} %%% just a synonym
  76.  
  77. \def \Multiply #1by #2%%% allows division of a dimen by a dimen
  78.        {{%%% should really freeze parameter 2 (dimen, passed by value)
  79.     \count 0 = #1\relax
  80.     \count 2 = #2\relax
  81.     \count 4 = 65536
  82.     \Message {Before scaling, count 0 = \the \count 0 \space and
  83.             count 2 = \the \count 2}%
  84.     \ifnum    \count 0 > 32767 %%% do our best to avoid overflow
  85.     \then    \divide \count 0 by 4
  86.         \divide \count 4 by 4
  87.     \else    \ifnum    \count 0 < -32767
  88.         \then    \divide \count 0 by 4
  89.             \divide \count 4 by 4
  90.         \else
  91.         \fi
  92.     \fi
  93.     \ifnum    \count 2 > 32767 %%% while retaining reasonable accuracy
  94.     \then    \divide \count 2 by 4
  95.         \divide \count 4 by 4
  96.     \else    \ifnum    \count 2 < -32767
  97.         \then    \divide \count 2 by 4
  98.             \divide \count 4 by 4
  99.         \else
  100.         \fi
  101.     \fi
  102.     \multiply \count 0 by \count 2
  103.     \divide \count 0 by \count 4
  104.     \xdef \product {#1 = \the \count 0 \internalunits}%
  105.     \aftergroup \product
  106.        }}
  107.  
  108. \def \Sin (#1)%
  109.        {{%
  110.     \dimen 0 = #1 \radian
  111.     \dimen 2 = 3.1415926535897963 \radian %%% a well-known constant
  112.     \divide    \dimen 2 by 2 %%% we only deal with -pi/2 : pi/2
  113.     \ifdim    \dimen 0 > \dimen 2
  114.     \then    \message {Sin: argument (\nodimen 0) too large
  115.                         --- use range reduction}%
  116.         \xdef \sine {<undefined>}%
  117.     \else    \ifdim    \dimen 0 < - \dimen 2
  118.         \then    \message {Sin: argument (\nodimen 0) too large
  119.                         --- use range reduction}%
  120.             \xdef \sine {<undefined>}%
  121.         \else    \Message {Sin: calculating Sin of \nodimen 0}%
  122.             \count 0 = 1 %%% see power-series expansion for sine
  123.             \dimen 2 = 1 \radian %%% ditto
  124.             \dimen 4 = 0 \radian %%% ditto
  125.             \loop
  126.                 \ifnum    \dimen 2 = 0 %%% then we've done
  127.                 \then    \stillconvergingfalse
  128.                 \else    \stillconvergingtrue
  129.                 \fi
  130.                 \ifstillconverging %%% then calculate next term
  131.                 \then    \term {\count 0} {\dimen 0} {\dimen 2}%
  132.                     \advance \count 0 by 2
  133.                     \count 2 = \count 0
  134.                     \divide \count 2 by 2
  135.                     \ifodd    \count 2 %%% signs alternate
  136.                     \then    \advance \dimen 4 by \dimen 2
  137.                     \else    \advance \dimen 4 by -\dimen 2
  138.                     \fi
  139.             \repeat
  140.             \xdef \sine {\nodimen 4}%
  141.         \fi
  142.     \fi
  143.     \aftergroup \sine
  144.        }}
  145.  
  146. %%% What follows is just a demonstration of the \Sin function
  147.  
  148. $$
  149. \def \rule {\noalign {\hrule}}
  150. \def \SIN (#1){&&\Sin (#1)&\cr\noalign{\message {The sine of #1 is \sine}}}
  151. \mathcode `\- = 32768 %%% just a bodge to improve alignment
  152. \let \minus = -
  153. \begingroup
  154. \catcode `\- = \active
  155. \gdef -{\llap{\minus}}
  156. \endgroup
  157. \vbox {\offinterlineskip
  158. \halign
  159. {\vrule #& \qquad \hfil $#$ & \vrule # & \qquad $#$ \hfil & \vrule # \strut \cr
  160.     \rule
  161.     &\omit {\hfil $x$ \hfil} && \omit {\hfil $\sin x$ \hfil} & \cr
  162.     \rule
  163.     \SIN (-1.6)
  164.     \SIN (-1.5)
  165.     \SIN (-1.4)
  166.     \SIN (-1.3)
  167.     \SIN (-1.2)
  168.     \SIN (-1.1)
  169.     \SIN (-1.0)
  170.     \SIN (-0.9)
  171.     \SIN (-0.8)
  172.     \SIN (-0.7)
  173.     \SIN (-0.6)
  174.     \SIN (-0.5)
  175.     \SIN (-0.4)
  176.     \SIN (-0.3)
  177.     \SIN (-0.2)
  178.     \SIN (-0.1)
  179.     \SIN (-0.01)
  180.     \SIN (-0.001)
  181.     \SIN (-0.0001)
  182.     \SIN (0)
  183.     \SIN (0.0001)
  184.     \SIN (0.001)
  185.     \SIN (0.01)
  186.     \SIN (0.1)
  187.     \SIN (0.2)
  188.     \SIN (0.3)
  189.     \SIN (0.4)
  190.     \SIN (0.5)
  191.     \SIN (0.6)
  192.     \SIN (0.7)
  193.     \SIN (0.8)
  194.     \SIN (0.9)
  195.     \SIN (1.0)
  196.     \SIN (1.1)
  197.     \SIN (1.2)
  198.     \SIN (1.3)
  199.     \SIN (1.4)
  200.     \SIN (1.5)
  201.     \SIN (1.6)
  202.     \rule}
  203. }
  204. $$
  205. \end
  206.  
  207.